﻿using System;
using System.Threading.Tasks;

namespace ESRI.ArcGIS.Client.Async
{
    public static partial class IdentityManagerExtensions
    {
        #region GenerateCredentialTaskAsync

        /// <summary>
        /// Generates a token credential object asynchronously. You need to provide the service URL, the username and the password.
        /// This is a helper method typically called by the UI challenging the user.
        /// </summary>
        /// <param name="identityManager"></param>
        /// <param name="url">The URL.</param>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        /// <param name="generateTokenOptions">The optional infos concerning the token to generate (referer, proxyURL).</param>
        /// <returns></returns>
        public static Task<IdentityManager.Credential> GenerateCredentialTaskAsync(this IdentityManager identityManager,
            string url, string userName, string password, IdentityManager.GenerateTokenOptions generateTokenOptions)
        {
            if (identityManager == null) throw new ArgumentNullException("identityManager");
            var tcs = new TaskCompletionSource<IdentityManager.Credential>();
            identityManager.GenerateCredentialAsync(url, userName, password, (result, exception) =>
            {
                if (exception != null)
                    tcs.SetException(exception);
                else
                    tcs.SetResult(result);
            }, generateTokenOptions);

            return tcs.Task;
        }

        #endregion

        #region GetCredentialTaskAsync

        /// <summary>
        /// Returns a Credential object that can be used to access the secured resource identified by the input url.
        /// If required the user will be challenged for a username and password which is used to generate a token.
        /// The IdentityManager sets up a timer to update the Credential object with a new token prior to the expiration time.
        /// This method is typically called internally when a request fails due to an "invalid credentials" error.
        /// </summary>
        /// <param name="identityManager"></param>
        /// <param name="url">The url for the secure resource.</param>
        /// <param name="retry">Indicates if the method should make additional attempts to get the credentials after a failure
        /// (i.e. if true, the user will be challenged in any case)</param>
        /// <param name="generateTokenOptions">The optional infos concerning the credential to generate (referer, proxyURL).</param>
        /// <returns></returns>
        public static Task<IdentityManager.Credential> GetCredentialTaskAsync(this IdentityManager identityManager,
            string url, bool retry, IdentityManager.GenerateTokenOptions generateTokenOptions)
        {
            if (identityManager == null) throw new ArgumentNullException("identityManager");
            var tcs = new TaskCompletionSource<IdentityManager.Credential>();
            identityManager.GetCredentialAsync(url, retry, (result, exception) =>
            {
                if (exception != null)
                    tcs.SetException(exception);
                else
                    tcs.SetResult(result);
            }, generateTokenOptions);

            return tcs.Task;
        }

        #endregion

    }
}